home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / DeveloperLabs / Lab2 / CompositeView.m < prev    next >
Text File  |  1995-06-12  |  7KB  |  231 lines

  1. // CompositeView implements a view with three horizontal, equal-sized areas.
  2. // The left-most area is the "source," the middle area is the "destination,"
  3. // and the right-most area is the "result." CompositeView assures that the
  4. // contents of the result area is always generated by compositing the other
  5. // two areas using the compositing mode set in the setOperator: method.
  6. // It is also possible to change the contents, color, and alpha of the
  7. // source and destination areas; see the methods setSourceGray:, 
  8. // setSourceAlpha:, etc.
  9.  
  10. // CompositeView written by Bruce Blumberg and Ali Ozer, NeXT Developer Support
  11.  
  12. #import "CompositeView.h"
  13.  
  14. #import <appkit/Bitmap.h>
  15. #import <appkit/Control.h>
  16. #import <appkit/Matrix.h>
  17. #import <appkit/Window.h>
  18.  
  19. #import <dpsclient/wraps.h>
  20.  
  21. @implementation CompositeView
  22.  
  23. // The possible draw modes for the source.
  24. // In this version, only TRIANGLE is implemented.
  25.  
  26. #define TRIANGLE 0
  27. #define CIRCLE   1
  28. #define DIAMOND  2
  29. #define HEART    3
  30. #define FLOWER   4
  31.  
  32. // newFrame creates the view, initializes the rectangles that define the
  33. // three areas described above, and creates the bitmaps used for rendering the
  34. // source and destination bitmaps.
  35.  
  36. +newFrame:(const NXRect *)tF
  37. {
  38.     // Create the view
  39.     self = [super newFrame:tF];
  40.  
  41.     // EXERCISE: Make rectangles for source, destination and result.
  42.     // You'll need to initialize the three rectangles (sRect, dRect, rRect)
  43.     // so that they define the three areas in the view where the source,
  44.     // destination, and result images will appear...
  45.  
  46.     // Create bitmap for source image. Bitmaps are flipped by default;
  47.     // make sure we make ours not-flipped.
  48.  
  49.     source = [Bitmap newSize:sRect.size.width :sRect.size.height
  50.             type:NX_UNIQUEBITMAP];
  51.     [source setFlip:NO];
  52.     
  53.     // EXERCISE: Now create bitmap for the destination image...
  54.  
  55.     // Set the default operator and source picture. Also set default 
  56.     // gray and alpha values. You will of course have to make sure
  57.     // the sliders in your Interface Builder window have the same values.
  58.     // (This is a problem; can you see a way to fix it?)
  59.  
  60.     operator = NX_COPY;
  61.     sourcePicture = TRIANGLE;
  62.     sourceGray = 0.333; // dark gray
  63.     destGray = 0.666;   // light gray
  64.     sourceAlpha = 1.0;  // opaque
  65.     destAlpha = 1.0;    // opaque
  66.  
  67.     // Create the bitmap images using the initial values set above
  68.  
  69.     [self drawSource];
  70.     [self drawDestination];
  71.  
  72.     return self;
  73. }
  74.  
  75. // drawSource creates the source image in the source bitmap. Note that
  76. // drawSource does not render in the view; it renders in the bitmap only.
  77.  
  78. -drawSource
  79. {    
  80.     [source lockFocus];
  81.     PScompositerect (0.0, 0.0, sRect.size.width, sRect.size.height, NX_CLEAR);
  82.     PSsetgray(sourceGray);
  83.     PSsetalpha(sourceAlpha);
  84.     PSnewpath();
  85.     switch (sourcePicture) {
  86.     case TRIANGLE: 
  87.          PSmoveto (0.0, 0.0);
  88.         PSlineto (0.0, sRect.size.height);
  89.         PSlineto (sRect.size.width, sRect.size.height);
  90.         break;
  91.     //
  92.     // EXERCISE: Add code to draw the other images (defined above).
  93.         // You might want to use the demo programs Draw and/or Yap if the idea
  94.         // of hacking PostScript doesn't appeal to you.
  95.     //
  96.     default:
  97.         break;
  98.     }
  99.     PSclosepath();
  100.     PSfill();
  101.     [source unlockFocus];
  102.  
  103.     return self;
  104. }
  105.  
  106. // drawDestination creates the destination image in the destination bitmap. 
  107. // Like drawSource, drawDestination only draws in the bitmap, not the view.
  108.  
  109. -drawDestination
  110. {
  111.    // EXERCISE: drawDestination needs to be written; it draws the destination
  112.    // image in the destination bitmap. This method is very similar to 
  113.    // drawSource, except it needs to draw a triangle oriented differently.
  114.    // drawDestination also does not need to draw the other images (just
  115.    // a triangle is enough).
  116.  
  117.    return self;
  118. }
  119.  
  120. // setSourcePicture allows setting the picture to be drawn in the source
  121. // bitmap. Buttons connected to this method should have tags that are 
  122. // set to the various possible pictures (see the "#define"s, above).
  123. //
  124. // After setting the sourcePicture instance variable, setSourcePicture redraws
  125. // the bitmap and updates the view to reflect the new configuration.
  126.  
  127. // EXERCISE: Make setSourcePicture do what the comment above says it should do.
  128. // Of course, the harder problem is actually creating the different pictures.
  129.  
  130. -setSourcePicture:(id)ctl
  131. {
  132.     return self;
  133. }
  134.  
  135. // The following four methods set the color parameters and update
  136. // the source or destination bitmaps and the view to reflect the change.
  137. //
  138. // EXERCISE: You will need to fill in the methods to set the alpha 
  139. // values for the source and the destination. (They'll probably look very
  140. // similar to the following two...)
  141.  
  142. -setSourceGray:(id)ctl
  143. {
  144.     sourceGray = [ctl floatValue];
  145.     [self drawSource];
  146.     [self display];
  147.     return self;
  148. }
  149.  
  150. -setDestGray:(id)ctl
  151. {
  152.     destGray = [ctl floatValue];
  153.     [self drawDestination];
  154.     [self display];
  155.     return self;
  156. }
  157.  
  158. - setSourceAlpha:(id)ctl
  159. {
  160.     return self;
  161. }
  162.  
  163. - setDestAlpha:(id)ctl
  164. {
  165.     return self;
  166. }
  167.  
  168.  
  169. // The operator method returns the operator currently in use.
  170.  
  171. -(int)operator {return operator;}
  172.  
  173.  
  174. // setOperator sets the operator to be used in the compositing operations
  175. // and updates the view to reflect the change. Note that setOperator needs
  176. // to be connected to a row of buttons.
  177.  
  178. -setOperator:(id)sender
  179. {    
  180.     switch ([sender selectedRow]) {
  181.     case 0: operator = NX_COPY;        break;
  182.     case 1: operator = NX_CLEAR;         break;
  183.     case 2: operator = NX_SOVER;         break;
  184.     case 3: operator = NX_DOVER;        break;
  185.     case 4: operator = NX_SIN;         break;
  186.     case 5: operator = NX_DIN;         break;
  187.     case 6: operator = NX_SOUT;        break;
  188.     case 7: operator = NX_DOUT;        break;
  189.     case 8: operator = NX_SATOP;        break; 
  190.     case 9: operator = NX_DATOP;        break;
  191.     case 10: operator = NX_XOR;         break;
  192.     case 11: operator = NX_PLUSD;        break;
  193.     case 12: operator = NX_PLUSL;        break;
  194.     default: break;
  195.     }
  196.     [self display];
  197.  
  198.     return self;
  199. }
  200.  
  201.         
  202. // drawSelf:: simply redisplays the contents of the view. The source and
  203. // destination rectangles are updated from the bitmaps while the result
  204. // rectangle is created by compositing the two bitmaps.
  205.  
  206. -drawSelf:(NXRect *)r :(int) count
  207. {
  208.     // Erase the whole view
  209.     NXEraseRect(&bounds);
  210.  
  211.     // Draw the source bitmap and then frame it with black
  212.     [source composite:NX_COPY toPoint:&sRect.origin];
  213.     PSsetgray(NX_BLACK);
  214.     NXFrameRect(&sRect);
  215.  
  216.     // Draw the destination bitmap and frame it with black 
  217.     [destination composite:NX_COPY toPoint:&dRect.origin];
  218.     PSsetgray(NX_BLACK);
  219.     NXFrameRect(&dRect);
  220.  
  221.     // And now create the destination image and frame it with black as well
  222.     [destination composite:NX_COPY toPoint:&rRect.origin];
  223.     [source composite:operator toPoint:&rRect.origin];
  224.     PSsetgray(NX_BLACK);
  225.     NXFrameRect(&rRect);
  226.  
  227.     return self;
  228. }
  229.  
  230. @end
  231.